// （亟待完善）build_FuncFParam_TAC 表达式

#ifndef TACH
#define TACH

#include "../include/cds.h"
#include "ast.h"

/*
	1. 数组中的数表示形式为： 变量名 '#' 偏移量
	2. 临时变量,变量名首字母为%
	3. TACType类型中以及有含义的各个位置
			TACType_Def = 282,	x = y op z
				dest = x;
				(left = y; op = op;)可能没有
				right = z;
				type = TACType_Def;
			TACType_Go = 283,
				dest = #20;
				type = TACType_Go
			TACType_IfGo = 284, if y op z
				dest = #20(跳转到的三地址代码的标号 或者 标签名TACType_DefLabel);
				left = y;
				(op = op; right = z;)可能没有
				type = TACType_IfGo;
			TACType_BeginFunc = 285,
				dest = 函数名;
				type = TACType_BeginFunc;
			TACType_DefFunc = 291
				dest = 函数名
				op = 声明了多少变量 的 大小
				type = TACType_DefFunc
			TACType_EndFunc = 286,
				dest = 函数名
				type = TACType_EndFunc
			TACType_Param = 289,
				dest = 进来的形参名 或 传入的实参名;
				op = 当是数组时,即数组指针,该值为 '*' 
				type = TACType_Param
			TACType_Return = 290,
				type = TACType_Return; dest = 返回的值
			TACType_DefFunc = 291,
				type = TACType_Return; dest = 函数名

	4. 常量为 #123 字符串型
	5. (待优化)常量转换成 %ti = #123 型，并非直接压栈；具体位置 buildTAC-> case NUMBER
	6. (待优化)int FuncFrom 是函数开始的坐标，与char * FuncName; 作用相同，暂时不用FuncFrom 但保留, 未来是否能应用在多线程？
*/

enum TACType
{
	TACType_Def = 282,	// x = y op z; x = op y; x = y; x = y[i]; /* x[i] = y */
	TACType_Go = 283,	// goto
	TACType_IfGo = 284, // if TRUE goto
	TACType_BeginFunc = 285,// 调用函数
	//TACType_ArraytoVar = 287, // x[i] = y    TAC->left = i;TAC->right = y;TAC->dest = x
	//TACType_VartoArray = 288, // x = y[i]	TAC->left = i;TAC->right = y;TAC->dest = x
	TACType_Param = 289,// 参数压栈&取出参数
	TACType_Return = 290,// 返回
	TACType_DefFunc = 291,// 声明函数
	TACType_EndFunc = 286,// 结束声明
	TACType_DefLabel = 292// 标记// 是不是跟声明函数有点冲突?
};

typedef struct TAC *pTAC;
typedef struct TAC
{
	int node_ID;// ID名
	enum TACType type;// TACType 类型
	int op;	  //操作符// 需改为 enum 型

	char *dest; 
	char *left;	 
	char *right; 
	
	pTAC next;
	pTAC last;

	int register_Index[3];//寄存器分配情况，值若为-1表示在内存中，其他则为寄存器编号
}TAC;

// 初始化符号表等
void initlistmap();

// 生成TAC节点
pTAC newTACnode();

// 将两个TAC节点相连接
void conect_TAC(pTAC* pTAC1, pTAC* pTAC2);

// 生成新的临时变量
char *newTempID(int FuncFrom);

// while 语句的回填
void backfill(pTAC node, int start, int end);

// 将数字转化成字符串// 主要用于跳转,跳转到具体的TAC node->ID
char* buildNUM(int i);

// 数组的相关处理
int handleconstexps(past node, int** dim);

// 将压入栈中的字符串取出
char* ListGet();

// 跳转表，根据ast node->ast_ID知道这是什么类型的节点，
// 然后跳转到相应位置处理
pTAC buildTAC(past node, int FuncFrom);

pTAC build_FuncDef_TAC(past node, int FuncFrom);

pTAC build_FuncFParam_TAC(past node, int FuncFrom);

pTAC build_VarDecl_TAC(past node, int FuncFrom);

pTAC build_VarDef_TAC(past node, int FuncFrom);

pTAC build_InitVal_TAC(past node, int FuncFrom);

pTAC build_ConstDecl_TAC(past node, int FuncFrom);

pTAC build_ConstDef_TAC(past node, int FuncFrom);

pTAC build_ConstExps_TAC(past node, int FuncFrom);

pTAC build_ConstInitVal_TAC(past node, int FuncFrom);

pTAC build_Block_TAC(past node, int FuncFrom);

pTAC build_Stmt_TAC(past node, int FuncFrom);

pTAC build_LVal_TAC(past node, int FuncFrom);

pTAC build_Exps_TAC(past node, int FuncFrom);

pTAC build_UnaryExp_TAC(past node, int FuncFrom);

pTAC build_FuncRParams_TAC(past node, int FuncFrom);

pTAC build_Expr_TAC(past node, int FuncFrom);

void printfTAC(pTAC node);

// 初值的赋值与赋值初值的TAC的生成
pTAC buildTACInitVal(int dim[], char name[], past node, int dimcount, int FuncFrom, int dimmax);

// void newFuncDecl_SYM(past String, int RETURN_TYPE, int Start_ID);
// void newVarecl_SYM(past String, int TYPE1, int TYPE2, int VALUE);
// void newVarsecl_SYM(past String, int TYPE1, int TYPE2, int DIM, int VALUES[]);

typedef struct TACHeadList *pTACHeadList;
typedef struct TACHeadList
{
	pTACHeadList left, right; //上一个代码块和下一个代码块
	pTAC headnode;
} TACHeadList;

#endif